package org.ru.mse10.cvis.entity.cv;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.ru.mse10.cvis.entity.fs.File;
import org.ru.mse10.cvis.entity.misc.Identity;
import org.ru.mse10.cvis.entity.util.Bidirectional;

/**
 * The Class CvData.
 */
@Entity
@Table(name = "cv_data")
public class CvData extends Identity implements Bidirectional {

	/** The address. */
	private Address address = new Address();

	/** The language. */
	private String language;

	/** The personal information. */
	private PersonalInformation personalInformation = new PersonalInformation();

	/** The education entries. */
	private List<EducationEntry> educationEntries = new ArrayList<EducationEntry>();

	/** The language skills. */
	private List<LanguageSkill> languageSkills = new ArrayList<LanguageSkill>();

	/** The membership of professional bodies. */
	private List<MembershipOfProfessionalBody> membershipOfProfessionalBodies = new ArrayList<MembershipOfProfessionalBody>();

	/** The other skills. */
	private List<Skill> otherSkills = new ArrayList<Skill>();

	/** The years within companies. */
	private List<YearsWithinACompany> yearsWithinCompanies = new ArrayList<YearsWithinACompany>();

	/** The key qualifications. */
	private List<KeyQualification> keyQualifications = new ArrayList<KeyQualification>();

	/** The professional expiriance. */
	private Set<WorkExpirience> professionalExpiriance = new HashSet<WorkExpirience>();

	/** The other expirience. */
	private List<OtherExpirience> otherExpirience = new ArrayList<OtherExpirience>();

	/** The user. */
	private User user;

	/** The associated files. */
	private Set<File> associatedFiles = new HashSet<File>();

	/** The cv picture. */
	private File cvPicture;

	/** The positions. */
	private List<Position> positions = new ArrayList<Position>();

	/**
	 * Gets the language.
	 * 
	 * @return the language
	 */
	public String getLanguage() {
		return language;
	}

	/**
	 * Sets the language.
	 * 
	 * @param language
	 *            the new language
	 */
	public void setLanguage(String language) {
		this.language = language;
	}

	/**
	 * Gets the personal information.
	 * 
	 * @return the personal information
	 */
	@OneToOne(cascade = CascadeType.ALL)
	public PersonalInformation getPersonalInformation() {
		return personalInformation;
	}

	/**
	 * Gets the address.
	 * 
	 * @return the address
	 */
	@OneToOne(cascade = CascadeType.ALL)
	public Address getAddress() {
		return address;
	}

	/**
	 * Sets the address.
	 * 
	 * @param address
	 *            the new address
	 */
	public void setAddress(Address address) {
		this.address = address;
	}

	/**
	 * Sets the personal information.
	 * 
	 * @param personalInformation
	 *            the new personal information
	 */
	public void setPersonalInformation(PersonalInformation personalInformation) {
		this.personalInformation = personalInformation;
	}

	/**
	 * Gets the education entries.
	 * 
	 * @return the education entries
	 */
	@OneToMany(mappedBy = "cvData", cascade = CascadeType.ALL, orphanRemoval = true)
	public List<EducationEntry> getEducationEntries() {
		return educationEntries;
	}

	/**
	 * Sets the education entries.
	 * 
	 * @param educationEntries
	 *            the new education entries
	 */
	public void setEducationEntries(List<EducationEntry> educationEntries) {
		this.educationEntries = educationEntries;
	}

	/**
	 * Gets the language skills.
	 * 
	 * @return the language skills
	 */
	@OneToMany(mappedBy = "cvData", cascade = CascadeType.ALL, orphanRemoval = true)
	public List<LanguageSkill> getLanguageSkills() {
		return languageSkills;
	}

	/**
	 * Sets the language skills.
	 * 
	 * @param languageSkills
	 *            the new language skills
	 */
	public void setLanguageSkills(List<LanguageSkill> languageSkills) {
		this.languageSkills = languageSkills;
	}

	/**
	 * Gets the membership of professional bodies.
	 * 
	 * @return the membership of professional bodies
	 */
	@OneToMany(mappedBy = "cvData", cascade = CascadeType.ALL, orphanRemoval = true)
	public List<MembershipOfProfessionalBody> getMembershipOfProfessionalBodies() {
		return membershipOfProfessionalBodies;
	}

	/**
	 * Sets the membership of professional bodies.
	 * 
	 * @param membershipOfProfessionalBodies
	 *            the new membership of professional bodies
	 */
	public void setMembershipOfProfessionalBodies(
			List<MembershipOfProfessionalBody> membershipOfProfessionalBodies) {
		this.membershipOfProfessionalBodies = membershipOfProfessionalBodies;
	}

	/**
	 * Gets the other skills.
	 * 
	 * @return the other skills
	 */
	@OneToMany(mappedBy = "cvData", cascade = CascadeType.ALL)
	public List<Skill> getOtherSkills() {
		return otherSkills;
	}

	/**
	 * Sets the other skills.
	 * 
	 * @param otherSkills
	 *            the new other skills
	 */
	public void setOtherSkills(List<Skill> otherSkills) {
		this.otherSkills = otherSkills;
	}

	/**
	 * Gets the years within companies.
	 * 
	 * @return the years within companies
	 */
	@OneToMany(mappedBy = "cvData", cascade = CascadeType.ALL)
	public List<YearsWithinACompany> getYearsWithinCompanies() {
		return yearsWithinCompanies;
	}

	/**
	 * Sets the years within companies.
	 * 
	 * @param yearsWithinCompanies
	 *            the new years within companies
	 */
	public void setYearsWithinCompanies(
			List<YearsWithinACompany> yearsWithinCompanies) {
		this.yearsWithinCompanies = yearsWithinCompanies;
	}

	/**
	 * Gets the key qualifications.
	 * 
	 * @return the key qualifications
	 */
	@OneToMany(mappedBy = "cvData", cascade = CascadeType.ALL)
	public List<KeyQualification> getKeyQualifications() {
		return keyQualifications;
	}

	/**
	 * Sets the key qualifications.
	 * 
	 * @param keyQualifications
	 *            the new key qualifications
	 */
	public void setKeyQualifications(List<KeyQualification> keyQualifications) {
		this.keyQualifications = keyQualifications;
	}

	/**
	 * Gets the professional expiriance.
	 * 
	 * @return the professional expiriance
	 */
	@OneToMany(mappedBy = "cvData", cascade = CascadeType.ALL)
	public Set<WorkExpirience> getProfessionalExpiriance() {
		return professionalExpiriance;
	}

	/**
	 * Sets the professional expiriance.
	 * 
	 * @param professionalExpiriance
	 *            the new professional expiriance
	 */
	public void setProfessionalExpiriance(
			Set<WorkExpirience> professionalExpiriance) {
		this.professionalExpiriance = professionalExpiriance;
	}

	/**
	 * Gets the other expirience.
	 * 
	 * @return the other expirience
	 */
	@OneToMany(mappedBy = "cvData", cascade = CascadeType.ALL, orphanRemoval = true)
	public List<OtherExpirience> getOtherExpirience() {
		return otherExpirience;
	}

	/**
	 * Sets the other expirience.
	 * 
	 * @param otherExpirience
	 *            the new other expirience
	 */
	public void setOtherExpirience(List<OtherExpirience> otherExpirience) {
		this.otherExpirience = otherExpirience;
	}

	/**
	 * Gets the user.
	 * 
	 * @return the user
	 */
	@ManyToOne
	public User getUser() {
		return user;
	}

	/**
	 * Sets the user.
	 * 
	 * @param user
	 *            the new user
	 */
	public void setUser(User user) {
		this.user = user;
	}

	/**
	 * Gets the associated files.
	 * 
	 * @return the associated files
	 */
	@OneToMany(cascade = CascadeType.ALL)
	public Set<File> getAssociatedFiles() {
		return associatedFiles;
	}

	/**
	 * Sets the associated files.
	 * 
	 * @param associatedFiles
	 *            the new associated files
	 */
	public void setAssociatedFiles(Set<File> associatedFiles) {
		this.associatedFiles = associatedFiles;
	}

	/**
	 * Gets the cv picture.
	 * 
	 * @return the cv picture
	 */
	@OneToOne(cascade = CascadeType.ALL)
	public File getCvPicture() {
		return cvPicture;
	}

	/**
	 * Sets the cv picture.
	 * 
	 * @param cvPicture
	 *            the new cv picture
	 */
	public void setCvPicture(File cvPicture) {
		this.cvPicture = cvPicture;
	}

	/**
	 * Gets the positions.
	 * 
	 * @return the positions
	 */
	@OneToMany(cascade = CascadeType.ALL, mappedBy = "cvData", orphanRemoval = true)
	public List<Position> getPositions() {
		return positions;
	}

	/**
	 * Sets the positions.
	 * 
	 * @param positions
	 *            the new positions
	 */
	public void setPositions(List<Position> positions) {
		this.positions = positions;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.ru.mse10.cvis.entity.util.Bidirectional#initializeBidirectionalReferences
	 * ()
	 */
	@Override
	public void initializeBidirectionalReferences() {
		for (EducationEntry entry : getEducationEntries()) {
			entry.setCvData(this);
		}
		for (LanguageSkill skill : getLanguageSkills()) {
			skill.setCvData(this);
		}
		for (OtherExpirience expirience : getOtherExpirience()) {
			expirience.setCvData(this);
		}
		for (MembershipOfProfessionalBody membership : getMembershipOfProfessionalBodies()) {
			membership.setCvData(this);
		}
		for (KeyQualification qualification : getKeyQualifications()) {
			qualification.setCvData(this);
		}
		for (Skill skill : getOtherSkills()) {
			skill.setCvData(this);
		}
		for (Position position : getPositions()) {
			position.setCvData(this);
		}
	}
}
